home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / actionrp / lrogue0.1 / lrogue0 / rogue / pack.c < prev    next >
C/C++ Source or Header  |  1992-09-26  |  10KB  |  520 lines

  1. /*
  2.  * pack.c
  3.  *
  4.  * This source herein may be modified and/or distributed by anybody who
  5.  * so desires, with the following restrictions:
  6.  *    1.)  No portion of this notice shall be removed.
  7.  *    2.)  Credit shall not be taken for the creation of this source.
  8.  *    3.)  This code is not to be traded, sold, or used for personal
  9.  *         gain or profit.
  10.  *
  11.  */
  12.  
  13. #ifndef CURSES
  14. #include <curses.h>
  15. #endif CURSES
  16. #include "rogue.h"
  17.  
  18. char *curse_message = "you can't, it appears to be cursed";
  19.  
  20. object *
  21. add_to_pack(obj, pack, condense)
  22. object *obj, *pack;
  23. {
  24.     object *op;
  25.  
  26.     if (condense) {
  27.         if (op = check_duplicate(obj, pack)) {
  28.             free_object(obj);
  29.             return(op);
  30.         } else {
  31.             obj->ichar = next_avail_ichar();
  32.         }
  33.     }
  34.     if (pack->next_object == 0) {
  35.         pack->next_object = obj;
  36.     } else {
  37.         op = pack->next_object;
  38.  
  39.         while (op->next_object) {
  40.             op = op->next_object;
  41.         }
  42.         op->next_object = obj;
  43.     }
  44.     obj->next_object = 0;
  45.     return(obj);
  46. }
  47.  
  48. take_from_pack(obj, pack)
  49. object *obj, *pack;
  50. {
  51.     while (pack->next_object != obj) {
  52.         pack = pack->next_object;
  53.     }
  54.     pack->next_object = pack->next_object->next_object;
  55. }
  56.  
  57. object *
  58. pick_up(row, col, status)
  59. short *status;
  60. {
  61.     object *obj;
  62.  
  63.     obj = object_at(&level_objects, row, col);
  64.     *status = 1;
  65.  
  66.     if ((obj->what_is == SCROLL) && (obj->which_kind == SCARE_MONSTER) &&
  67.         obj->picked_up) {
  68.         message("the scroll turns to dust as you pick it up", 0);
  69.         dungeon[row][col] &= (~OBJECT);
  70.         vanish(obj, 0, &level_objects);
  71.         *status = 0;
  72.         if (id_scrolls[SCARE_MONSTER].id_status == UNIDENTIFIED) {
  73.             id_scrolls[SCARE_MONSTER].id_status = IDENTIFIED;
  74.         }
  75.         return(0);
  76.     }
  77.     if (obj->what_is == GOLD) {
  78.         rogue.gold += obj->quantity;
  79.         dungeon[row][col] &= ~(OBJECT);
  80.         take_from_pack(obj, &level_objects);
  81.         print_stats(STAT_GOLD);
  82.         return(obj);    /* obj will be free_object()ed in one_move_rogue() */
  83.     }
  84.     if (pack_count(obj) >= MAX_PACK_COUNT) {
  85.         message("pack too full", 1);
  86.         return(0);
  87.     }
  88.     dungeon[row][col] &= ~(OBJECT);
  89.     take_from_pack(obj, &level_objects);
  90.     obj = add_to_pack(obj, &rogue.pack, 1);
  91.     obj->picked_up = 1;
  92.     return(obj);
  93. }
  94.  
  95. drop()
  96. {
  97.     object *obj, *new;
  98.     short ch;
  99.     char desc[DCOLS];
  100.  
  101.     if (dungeon[rogue.row][rogue.col] & (OBJECT | STAIRS | TRAP)) {
  102.         message("there's already something there", 0);
  103.         return;
  104.     }
  105.     if (!rogue.pack.next_object) {
  106.         message("you have nothing to drop", 0);
  107.         return;
  108.     }
  109.     if ((ch = pack_letter("drop what?", ALL_OBJECTS)) == CANCEL) {
  110.         return;
  111.     }
  112.     if (!(obj = get_letter_object(ch))) {
  113.         message("no such item.", 0);
  114.         return;
  115.     }
  116.     if (obj->in_use_flags & BEING_WIELDED) {
  117.         if (obj->is_cursed) {
  118.             message(curse_message, 0);
  119.             return;
  120.         }
  121.         unwield(rogue.weapon);
  122.     } else if (obj->in_use_flags & BEING_WORN) {
  123.         if (obj->is_cursed) {
  124.             message(curse_message, 0);
  125.             return;
  126.         }
  127.         mv_aquatars();
  128.         unwear(rogue.armor);
  129.         print_stats(STAT_ARMOR);
  130.     } else if (obj->in_use_flags & ON_EITHER_HAND) {
  131.         if (obj->is_cursed) {
  132.             message(curse_message, 0);
  133.             return;
  134.         }
  135.         un_put_on(obj);
  136.     }
  137.     obj->row = rogue.row;
  138.     obj->col = rogue.col;
  139.  
  140.     if ((obj->quantity > 1) && (obj->what_is != WEAPON)) {
  141.         obj->quantity--;
  142.         new = alloc_object();
  143.         *new = *obj;
  144.         new->quantity = 1;
  145.         obj = new;
  146.     } else {
  147.         obj->ichar = 'L';
  148.         take_from_pack(obj, &rogue.pack);
  149.     }
  150.     place_at(obj, rogue.row, rogue.col);
  151.     (void) strcpy(desc, "dropped ");
  152.     get_desc(obj, desc+8);
  153.     message(desc, 0);
  154.     (void) reg_move();
  155. }
  156.  
  157. object *
  158. check_duplicate(obj, pack)
  159. object *obj, *pack;
  160. {
  161.     object *op;
  162.  
  163.     if (!(obj->what_is & (WEAPON | FOOD | SCROLL | POTION))) {
  164.         return(0);
  165.     }
  166.     if ((obj->what_is == FOOD) && (obj->which_kind == FRUIT)) {
  167.         return(0);
  168.     }
  169.     op = pack->next_object;
  170.  
  171.     while (op) {
  172.         if ((op->what_is == obj->what_is) && 
  173.             (op->which_kind == obj->which_kind)) {
  174.  
  175.             if ((obj->what_is != WEAPON) ||
  176.             ((obj->what_is == WEAPON) &&
  177.             ((obj->which_kind == ARROW) ||
  178.             (obj->which_kind == DAGGER) ||
  179.             (obj->which_kind == DART) ||
  180.             (obj->which_kind == SHURIKEN)) &&
  181.             (obj->quiver == op->quiver))) {
  182.                 op->quantity += obj->quantity;
  183.                 return(op);
  184.             }
  185.         }
  186.         op = op->next_object;
  187.     }
  188.     return(0);
  189. }
  190.  
  191. next_avail_ichar()
  192. {
  193.     register object *obj;
  194.     register i;
  195.     boolean ichars[26];
  196.  
  197.     for (i = 0; i < 26; i++) {
  198.         ichars[i] = 0;
  199.     }
  200.     obj = rogue.pack.next_object;
  201.     while (obj) {
  202.         ichars[(obj->ichar - 'a')] = 1;
  203.         obj = obj->next_object;
  204.     }
  205.     for (i = 0; i < 26; i++) {
  206.         if (!ichars[i]) {
  207.             return(i + 'a');
  208.         }
  209.     }
  210.     return('?');
  211. }
  212.  
  213. wait_for_ack()
  214. {
  215.     while (rgetchar() != ' ') ;
  216. }
  217.  
  218. pack_letter(prompt, mask)
  219. char *prompt;
  220. unsigned short mask;
  221. {
  222.     short ch;
  223.     unsigned short tmask = mask;
  224.  
  225.     if (!mask_pack(&rogue.pack, mask)) {
  226.         message("nothing appropriate", 0);
  227.         return(CANCEL);
  228.     }
  229.     for (;;) {
  230.  
  231.         message(prompt, 0);
  232.  
  233.         for (;;) {
  234.             ch = rgetchar();
  235.             if (!is_pack_letter(&ch, &mask)) {
  236.                 sound_bell();
  237.             } else {
  238.                 break;
  239.             }
  240.         }
  241.  
  242.         if (ch == LIST) {
  243.             check_message();
  244.             inventory(&rogue.pack, mask);
  245.         } else {
  246.             break;
  247.         }
  248.         mask = tmask;
  249.     }
  250.     check_message();
  251.     return(ch);
  252. }
  253.  
  254. take_off()
  255. {
  256.     char desc[DCOLS];
  257.     object *obj;
  258.  
  259.     if (rogue.armor) {
  260.         if (rogue.armor->is_cursed) {
  261.             message(curse_message, 0);
  262.         } else {
  263.             mv_aquatars();
  264.             obj = rogue.armor;
  265.             unwear(rogue.armor);
  266.             (void) strcpy(desc, "was wearing ");
  267.             get_desc(obj, desc+12);
  268.             message(desc, 0);
  269.             print_stats(STAT_ARMOR);
  270.             (void) reg_move();
  271.         }
  272.     } else {
  273.         message("not wearing any", 0);
  274.     }
  275. }
  276.  
  277. wear()
  278. {
  279.     short ch;
  280.     register object *obj;
  281.     char desc[DCOLS];
  282.  
  283.     if (rogue.armor) {
  284.         message("your already wearing some", 0);
  285.         return;
  286.     }
  287.     ch = pack_letter("wear what?", ARMOR);
  288.  
  289.     if (ch == CANCEL) {
  290.         return;
  291.     }
  292.     if (!(obj = get_letter_object(ch))) {
  293.         message("no such item.", 0);
  294.         return;
  295.     }
  296.     if (obj->what_is != ARMOR) {
  297.         message("you can't wear that", 0);
  298.         return;
  299.     }
  300.     obj->identified = 1;
  301.     (void) strcpy(desc, "wearing ");
  302.     get_desc(obj, desc + 8);
  303.     message(desc, 0);
  304.     do_wear(obj);
  305.     print_stats(STAT_ARMOR);
  306.     (void) reg_move();
  307. }
  308.  
  309. unwear(obj)
  310. object *obj;
  311. {
  312.     if (obj) {
  313.         obj->in_use_flags &= (~BEING_WORN);
  314.     }
  315.     rogue.armor = (object *) 0;
  316. }
  317.  
  318. do_wear(obj)
  319. object *obj;
  320. {
  321.     rogue.armor = obj;
  322.     obj->in_use_flags |= BEING_WORN;
  323.     obj->identified = 1;
  324. }
  325.  
  326. wield()
  327. {
  328.     short ch;
  329.     register object *obj;
  330.     char desc[DCOLS];
  331.  
  332.     if (rogue.weapon && rogue.weapon->is_cursed) {
  333.         message(curse_message, 0);
  334.         return;
  335.     }
  336.     ch = pack_letter("wield what?", WEAPON);
  337.  
  338.     if (ch == CANCEL) {
  339.         return;
  340.     }
  341.     if (!(obj = get_letter_object(ch))) {
  342.         message("No such item.", 0);
  343.         return;
  344.     }
  345.     if (obj->what_is & (ARMOR | RING)) {
  346.         sprintf(desc, "you can't wield %s",
  347.             ((obj->what_is == ARMOR) ? "armor" : "rings"));
  348.         message(desc, 0);
  349.         return;
  350.     }
  351.     if (obj->in_use_flags & BEING_WIELDED) {
  352.         message("in use", 0);
  353.     } else {
  354.         unwield(rogue.weapon);
  355.         (void) strcpy(desc, "wielding ");
  356.         get_desc(obj, desc + 9);
  357.         message(desc, 0);
  358.         do_wield(obj);
  359.         (void) reg_move();
  360.     }
  361. }
  362.  
  363. do_wield(obj)
  364. object *obj;
  365. {
  366.     rogue.weapon = obj;
  367.     obj->in_use_flags |= BEING_WIELDED;
  368. }
  369.  
  370. unwield(obj)
  371. object *obj;
  372. {
  373.     if (obj) {
  374.         obj->in_use_flags &= (~BEING_WIELDED);
  375.     }
  376.     rogue.weapon = (object *) 0;
  377. }
  378.  
  379. call_it()
  380. {
  381.     short ch;
  382.     register object *obj;
  383.     struct id *id_table;
  384.     char buf[MAX_TITLE_LENGTH+2];
  385.  
  386.     ch = pack_letter("call what?", (SCROLL | POTION | WAND | RING));
  387.  
  388.     if (ch == CANCEL) {
  389.         return;
  390.     }
  391.     if (!(obj = get_letter_object(ch))) {
  392.         message("no such item.", 0);
  393.         return;
  394.     }
  395.     if (!(obj->what_is & (SCROLL | POTION | WAND | RING))) {
  396.         message("surely you already know what that's called", 0);
  397.         return;
  398.     }
  399.     id_table = get_id_table(obj);
  400.  
  401.     if (get_input_line("call it:","",buf,id_table[obj->which_kind].title,1,1)) {
  402.         id_table[obj->which_kind].id_status = CALLED;
  403.         (void) strcpy(id_table[obj->which_kind].title, buf);
  404.     }
  405. }
  406.  
  407. pack_count(new_obj)
  408. object *new_obj;
  409. {
  410.     object *obj;
  411.     short count = 0;
  412.  
  413.     obj = rogue.pack.next_object;
  414.  
  415.     while (obj) {
  416.         if (obj->what_is != WEAPON) {
  417.             count += obj->quantity;
  418.         } else if (!new_obj) {
  419.             count++;
  420.         } else if ((new_obj->what_is != WEAPON) ||
  421.             ((obj->which_kind != ARROW) &&
  422.             (obj->which_kind != DAGGER) &&
  423.             (obj->which_kind != DART) &&
  424.             (obj->which_kind != SHURIKEN)) ||
  425.             (new_obj->which_kind != obj->which_kind) ||
  426.             (obj->quiver != new_obj->quiver)) {
  427.             count++;
  428.         }
  429.         obj = obj->next_object;
  430.     }
  431.     return(count);
  432. }
  433.  
  434. boolean
  435. mask_pack(pack, mask)
  436. object *pack;
  437. unsigned short mask;
  438. {
  439.     while (pack->next_object) {
  440.         pack = pack->next_object;
  441.         if (pack->what_is & mask) {
  442.             return(1);
  443.         }
  444.     }
  445.     return(0);
  446. }
  447.  
  448. is_pack_letter(c, mask)
  449. short *c;
  450. unsigned short *mask;
  451. {
  452.     if (((*c == '?') || (*c == '!') || (*c == ':') || (*c == '=') ||
  453.         (*c == ')') || (*c == ']') || (*c == '/') || (*c == ','))) {
  454.         switch(*c) {
  455.         case '?':
  456.             *mask = SCROLL;
  457.             break;
  458.         case '!':
  459.             *mask = POTION;
  460.             break;
  461.         case ':':
  462.             *mask = FOOD;
  463.             break;
  464.         case ')':
  465.             *mask = WEAPON;
  466.             break;
  467.         case ']':
  468.             *mask = ARMOR;
  469.             break;
  470.         case '/':
  471.             *mask = WAND;
  472.             break;
  473.         case '=':
  474.             *mask = RING;
  475.             break;
  476.         case ',':
  477.             *mask = AMULET;
  478.             break;
  479.         }
  480.         *c = LIST;
  481.         return(1);
  482.     }
  483.     return(((*c >= 'a') && (*c <= 'z')) || (*c == CANCEL) || (*c == LIST));
  484. }
  485.  
  486. has_amulet()
  487. {
  488.     return(mask_pack(&rogue.pack, AMULET));
  489. }
  490.  
  491. kick_into_pack()
  492. {
  493.     object *obj;
  494.     char desc[DCOLS];
  495.     short n, stat;
  496.  
  497.     if (!(dungeon[rogue.row][rogue.col] & OBJECT)) {
  498.         message("nothing here", 0);
  499.     } else {
  500.         if (obj = pick_up(rogue.row, rogue.col, &stat)) {
  501.             get_desc(obj, desc);
  502.             if (obj->what_is == GOLD) {
  503.                 message(desc, 0);
  504.                 free_object(obj);
  505.             } else {
  506.                 n = strlen(desc);
  507.                 desc[n] = '(';
  508.                 desc[n+1] = obj->ichar;
  509.                desc[n+2] = ')';
  510.                 desc[n+3] = 0;
  511.                 message(desc, 0);
  512.             }
  513.         }
  514.         if (obj || (!stat)) {
  515.             (void) reg_move();
  516.         }
  517.     }
  518. }
  519.  
  520.